/**
 * Sslwrap
 *
 * @package     jquery
 * @subpackage  Sslwrap
 */

var Sslwrap = {
    /**
     * HTML 활성화 어트리뷰트 (활성화 : 1, 비활성화 : 0)
     * @var {string}
     */
    _attrKey : 'fw-sslwrap',

    /**
     * 암호화 전송 REQUEST 키
     * @var {string}
     */
    _rKey : null,
    /**
     * 암호화 배열 데이터 접두어 키
     * @var {string}
     */
    _rArrValPrefix : null,
    /**
     * 암호화 배열 데이터 구분자 키
     * @var {string}
     */
    _rArrValSep : null,
    /**
     * 암호화 데이터 UNSET 지시어
     * @var {string}
     */
    _rUnset : null,

    /**
     * 현재 암호화 대상 폼 아이디
     * @var {string}
     */
    _currEncFormId : null,
    /**
     * 현재 암호화 대상 엘리먼트
     * @var {object}
     * {
     *     type : array | single,
     *     list : [엘리먼트, ...]
     * }
     */
    _currEncTargets : null,
    /**
     * 현재 암호화 대상 엘리먼트 배열(AuthSSLManager 에 지정하는)
     * @var {array}
     * [REQUEST 키, ...]
     */
    _currEncTargetsArray : null,

    /**
     * 암호화 콜백
     * @var {string} | {function}
     */
    _currCallbackEnc : null,
    /**
     * 복호화 콜백
     * @var {string} | {function}
     */
    _currCallbackDec : null,

    /**
     * 암호화 옵션 초기화 여부
     * @var {boolean}
     */
    _isEncryptInit : false,

    /**
     * 암호화
     *
     * @param {object} options
     * {
     *     form : 폼아이디,
     *     all : true or false(전체 엘리먼트 지정 여부),
     *     callback : 콜백
     * }
     * @returns {boolean}
     */
    encrypt : function(options) {
        if (this._isEncryptInit !== true) {
            return false;
        }

        if (this._isEmpty(options) === true) {
            return false;
        }

        this._encryptCall(options.form, options.all, options.callback);

        return true;
    },

    /**
     * 복호화
     *
     * @param {object} options
     * {
     *     data : 암호화문자열,
     *     callback : 콜백
     * }
     * @returns {boolean}
     */
    decrypt : function(options) {
        if (this._isEmpty(options) === true) {
            return false;
        }

        this._decryptCall(options.data, options.callback);

        return true;
    },

    _encryptInit : function(options) {
        if (this._isEncryptInit === true) {
            return false;
        }

        if (this._isEmpty(options) === true) {
            return false;
        }

        this._rKey          = options.reqKey;
        this._rArrValPrefix = options.reqArrValuePrefix;
        this._rArrValSep    = options.reqArrValueSep;
        this._rUnset        = options.reqUnset;

        this._isEncryptInit = true;

        return true;
    },

    _encryptCall : function(form, all, callback) {
        this._currEncFormId         = form;
        this._currEncTargets        = this._parseTarget(all);
        this._currEncTargetsArray   = this._parseTargetArray(this._currEncTargets);
        this._currCallbackEnc       = callback;

        AuthSSLManager.weave({
            'auth_mode' : 'encrypt',
            'aEleId' : this._currEncTargetsArray,
            'auth_callbackName' : 'Sslwrap._encryptCallback'
        });
    },

    _decryptCall : function(data, callback) {
        this._currCallbackDec = callback;

        AuthSSLManager.weave({
            'auth_mode' : 'decryptClient',
            'auth_string' : data,
            'auth_callbackName' : 'Sslwrap._decryptCallback'
        });
    },

    _decryptCallback : function(response) {
        response = decodeURIComponent(response);
        var data = AuthSSLManager.unserialize(response);

        var result = {'result' : true, 'data' : data};

        this._callbackExecute(this._currCallbackDec, result);
    },

    _encryptCallback : function(response) {
        if (AuthSSLManager.isError(response) == true) {
            return;
        }

        this._preventPlainRequest();

        var elmForm = this._getForm();
        var elmHidden = '<input type="hidden" name="'+this._rKey+'" value="'+response+'">';

        elmForm.append(elmHidden);

        var result = {'result' : true, 'data' : response};

        this._callbackExecute(this._currCallbackEnc, result);
    },

    _callbackExecute : function(callback, response) {
        if (typeof callback == 'function') {

            return callback(response);

        } else if (typeof callback == 'string') {

            return window[callback](response);

        }

        return false;
    },

    _parseTarget : function(isAll) {
        var result = {};
        var elmForm = this._getForm();
        var elmsTarget = null;

        if (isAll === true) {
            elmsTarget = elmForm.find(':input[name][name!=""][' + this._attrKey + '!=0]');
        } else {
            elmsTarget = elmForm.find(':input[' + this._attrKey + '=1][name][name!=""]');
        }

        if (elmsTarget.length === 0) {
            return result;
        }


        elmsTarget.each(function() {
            var isDisabled = this.disabled;

            var name = this.getAttribute('name');
            var elmType = this.getAttribute('type');

            if (elmType) {
                elmType = elmType.toLowerCase();
            }

            var type = 'single';

            if (isDisabled === true || elmType == 'file') {
                return;
            }

            var el = $(this);

            if (/\[\]$/.test(name) === true) {
                name = name.replace(/\[\]$/, '');
                type = 'array';

                if (typeof result[name] != 'undefined') {
                    result[name].list.push(el);
                } else {
                    result[name] = {};
                    result[name].type = type;
                    result[name].list = [el];
                }
            } else {
                type = 'single';
                result[name] = {};
                result[name].type = type;
                result[name].list = [el];
            }
        });

        return result;
    },

    _parseTargetArray : function() {
        var r = [];
        var targets = this._currEncTargets;

        for (var i in targets) {
            r.push(i);
        }

        return r;
    },

    _getValueByTarget : function(name) {
        var target = this._currEncTargets[name];
        var result = '';

        if (this._isEmpty(target) === true) {
            return result;
        }

        var type = target.type;
        var len = target.list.length;

        if (type == 'array') {
            result = this._rArrValPrefix;
            var values = [];

            for (var i = 0; i < len; i++) {
                var elm = target.list[i];
                var val = this._getElmValue(elm);

                if (val !== false) {
                    values.push(val);
                }
            }

            if (this._isEmpty(values) === false) {
                result += values.join(this._rArrValSep);
            } else {
                result = this._rUnset;
            }
        } else {
            result = this._getElmValue(target.list[0]);
        }

        return result;
    },

    _getForm : function() {
        var id = this._currEncFormId;
        var idSelector = '#' + id;
        var nameSelector = '*[name="' + id + '"]';

        var elm = $(idSelector);

        if (elm.length > 0) {
            return elm;
        }

        elm = $(nameSelector);

        if (elm.length > 0) {
            return elm;
        }

        return false;
    },

    _getElmType : function(elm) {
        var elTag = elm[0].tagName;
        var result = null;

        switch (elTag) {
            case 'INPUT' :
                var _type = elm.attr('type').toLowerCase();
                if(_type == 'checkbox') result = 'checkbox';
                else if(_type =='radio') result = 'radio';
                else result = 'textbox';

                break;

            default :
                result = 'textbox';
                break;
        }

        return result;
    },

    _getElmValue : function(elm) {
        var result = false;
        var type = this._getElmType(elm);

        if (type == 'checkbox' || type == 'radio') {
            if (elm.get(0).checked === true) {
                result = elm.val();
            }

            return result;
        }

        return elm.val();
    },

    _preventPlainRequest : function() {
        if (this._isEmpty(this._currEncTargets) === true) {
            return false;
        }

        for (var i in this._currEncTargets) {
            var elm = this._currEncTargets[i];
            var len = elm.list.length;

            for (var j = 0; j < len; j++) {
                elm.list[j].attr('name', '');
                elm.list[j].attr('disabled', true);
            }
        }

        return true;
    },

    _isEmpty : function(vars) {
        var emptyTargets = [null, false, 0, ""];
        var len = emptyTargets.length;

        for (var i = 0; i < len; i++) {
            if (vars === emptyTargets[i]) {
                return true;
            }
        }

        if (typeof vars === 'object') {
            for (var i in vars) {
                return false;
            }

            return true;
        }

        return false;
    }
};


AuthSSLManager.getValue = function(name) {
    return Sslwrap._getValueByTarget(name);
};